package cn.sdnu.database.utils;

import cn.sdnu.database.controller.DbController;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Master_Joe qiaoguangtong@aliyun.com
 */
public class Utils {

	/**
	 * 获取当前数据库的物理路径, 在切换数据库的时候使用.
	 * 
	 * @param dbName 数据库的名字
	 * @return 数据库物理路径
	 */
	public static String getDatabasePath(String dbName) {
		String path = DbController.TEST_BASE + dbName + File.separator;
		return path;
	}

	/**
	 * 删除指定路径的名字
	 * 
	 * @param delPath
	 * @return {@code true} 删除成功, {@code false} 删除失败
	 */
	public static boolean deleteFile(String delPath) {
		try {
			File file = new File(delPath);
			if (!file.isDirectory()) {
				return file.delete();
			} else if (file.isDirectory()) {
				String[] fileList = file.list();
				for (int i = 0; i < fileList.length; i++) {
					File delFile = new File(delPath + File.separator + fileList[i]);
					if (!delFile.isDirectory()) {
						return delFile.delete();
					} else if (delFile.isDirectory()) {
						return deleteFile(delPath + File.separator + fileList[i]);
					} else {

					}
				}
				return file.delete();
			}

		} catch (Exception e) {
//			System.out.println("deletefile() Exception:" + e.getMessage());
			System.err.println("System error, exit");
			System.exit(0);
			return false;
		}
		return false;
	}

	/**
	 * 计算某字符在某字符串的个数
	 * 
	 * @param str 字符串
	 * @param c   字符
	 * @return 字符{@code c} 在字符串 {@code str} 中的个数
	 */
	public static int countString(String str, char c) {
		int count = 0;
		for (int i = 0; i < str.length(); i++) {
			if (str.charAt(i) == c) {
				count++;
			}
		}
		return count;
	}

	/**
	 * 检查括号 {} [] () 在字符串中是否是成对出现的
	 * 
	 * @param str         要检查的字符串
	 * @param leftBracket 要检查的括号的左边
	 * @return <code>true</code> 为括号成对出现, {@code false} 为括号不成对出现
	 */
	public static boolean matchBracket(String str, char leftBracket) {
		char rightBracket = ' ';
		if (leftBracket == '(') {
			rightBracket = ')';
		} else if (leftBracket == '{') {
			rightBracket = '}';
		} else if (leftBracket == '[') {
			rightBracket = ']';
		}
		return countString(str, leftBracket) == countString(str, rightBracket);
	}

	/**
	 * @return 所有的数据库的名字做成的集合
	 */
	public static List<String> getDatabases() {
		String path = DbController.TEST_BASE;
		File databasesFile = new File(path);
		File[] listFiles = databasesFile.listFiles();
		List<String> databasesList = new ArrayList<String>();
		for (File file : listFiles) {
			if (file.isDirectory()) {
				databasesList.add(file.getName());
			}
		}
		return databasesList;
	}

	/**
	 * 根据数据库的名字来获取当前数据库中的所有表
	 * 
	 * @param databaseName 数据库名字
	 * @return 所有表的String集合
	 */
	public static List<String> getTables(String databaseName) {
		List<String> databases = getDatabases();
		List<String> tables = new ArrayList<String>();
		if (databases.contains(databaseName)) {
			String databasePath = getDatabasePath(databaseName);
			File databaseFile = new File(databasePath);
			File[] listFiles = databaseFile.listFiles();
			for (File file : listFiles) {
				if (file.isFile() && file.getName().endsWith(DbController.EXTENSION)) {
					tables.add(file.getName().substring(0, file.getName().length() - 6));
				}
			}
			return tables;
		} else {
			return null;
		}
	}

	/**
	 * 获取特定数据库中特定表的所有列名
	 * 
	 * @param tableName    表名
	 * @param databaseName 列名
	 * @return
	 */
	public static List<String> getColumns(String tableName, String databaseName) {
		FileInputStream fileInputStream = null;
		List<String> columns = null;
		try {
			String path = DbController.TEST_BASE + databaseName + File.separator + tableName + DbController.EXTENSION;
			fileInputStream = new FileInputStream(new File(path));
			int len;
			byte[] buffer = new byte[1024];
			StringBuilder content = new StringBuilder();
			while ((len = fileInputStream.read(buffer)) != -1) {
				content.append(new String(buffer, 0, len));
			}
			String string = content.toString();
			int firstLineEndIndex = string.indexOf(DbController.END_INFO);
			String firstLine = string.substring(0, firstLineEndIndex);
			String realColumns = firstLine.substring(DbController.HEADER_INFO.length(), firstLineEndIndex);
			String[] columnsNames = realColumns.split(DbController.INTERVAL_INFO);
			columns = new ArrayList<String>();
			for (String string2 : columnsNames) {
				columns.add(string2);
			}
		} catch (Exception e) {
			System.err.println("System error, exit");
			System.exit(0);
		} finally {
			try {
				fileInputStream.close();
			} catch (IOException e) {
				System.err.println("System error, exit");
				System.exit(0);
			}
		}
		return columns;
	}

	/**
	 * 获取表的物理路径
	 * 
	 * @param tableName    表的名字
	 * @param databaseName 数据库的名字
	 * @return 指定数据库表的物理路径
	 */
	public static String getTablePath(String tableName, String databaseName) {
		String path = DbController.TEST_BASE + databaseName + File.separator + tableName + DbController.EXTENSION;
		return path;
	}

	/**
	 * 获取我们的表格的属性们
	 * 
	 * @param tableName
	 * @param databaseName
	 * @return
	 */
	public static List<String> getTypes(String tableName, String databaseName) {
		BufferedReader bufferedReader = null;
		List<String> types = null;
		try {
			String path = getTablePath(tableName, databaseName);
			bufferedReader = new BufferedReader(new FileReader(new File(path)));
			bufferedReader.readLine();
			String typesLine = bufferedReader.readLine();
			types = new ArrayList<String>();
			int firstLineEndIndex = typesLine.indexOf(DbController.END_INFO);
			String firstLine = typesLine.substring(0, firstLineEndIndex);
			String realColumns = firstLine.substring(DbController.HEADER_INFO.length(), firstLineEndIndex);
			String[] columnsNames = realColumns.split(DbController.INTERVAL_INFO);
			types = new ArrayList<String>();
			for (String string2 : columnsNames) {
				types.add(string2);
			}
		} catch (Exception e) {
			System.err.println("System error, exit");
			System.exit(0);
		} finally {
			try {
				bufferedReader.close();
			} catch (IOException e) {
				System.err.println("System error, exit");
				System.exit(0);
			}
		}
		return types;
	}

	/**
	 * 获取我们的表的额外信息, 例如 Primary key, not null 等等
	 * 
	 * @param tableName    数据表名字
	 * @param databaseName 数据库名字
	 * @return
	 */
	public static List<String> getExtra(String tableName, String databaseName) {
		BufferedReader bufferedReader = null;
		List<String> types = null;
		try {
			String path = getTablePath(tableName, databaseName);
			bufferedReader = new BufferedReader(new FileReader(new File(path)));
			bufferedReader.readLine();
			bufferedReader.readLine();
			String typesLine = bufferedReader.readLine();
			types = new ArrayList<String>();
			int firstLineEndIndex = typesLine.indexOf(DbController.END_INFO);
			String firstLine = typesLine.substring(0, firstLineEndIndex);
			String realColumns = firstLine.substring(DbController.HEADER_INFO.length(), firstLineEndIndex);
			String[] columnsNames = realColumns.split(DbController.INTERVAL_INFO);
			types = new ArrayList<String>();
			for (String string2 : columnsNames) {
				types.add(string2);
			}
		} catch (Exception e) {
			System.err.println("System error, exit");
			System.exit(0);
		} finally {
			try {
				bufferedReader.close();
			} catch (IOException e) {
				System.err.println("System error, exit");
				System.exit(0);
			}
		}
		return types;
	}

	/**
	 * 获得我们现在表中的数据是一个String类型的数据
	 * 
	 * @param tableName    表名字
	 * @param databaseName 数据库名字
	 * @return
	 */
	public static ArrayList<String> getTableContent(String tableName, String databaseName) {
		String tablePath = Utils.getTablePath(tableName, databaseName);
		BufferedReader bufferedReader = null;
		ArrayList<String> valueLines = null;
		try {
			bufferedReader = new BufferedReader(new FileReader(new File(tablePath)));
			bufferedReader.readLine();
			bufferedReader.readLine();
			bufferedReader.readLine();
			valueLines = new ArrayList<String>();
			String string = "";
			while ((string = bufferedReader.readLine()) != null) {
				valueLines.add(string);
			}
			return valueLines;
		} catch (Exception e) {
			System.err.println("System error, exit");
			System.exit(0);
		} finally {

			try {
				bufferedReader.close();
			} catch (IOException e) {
				System.err.println("System error, exit");
				System.exit(0);
			}
		}
		return null;
	}
	
	public static boolean delFile(File file) {
        if (!file.exists()) {
            return false;
        }

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                delFile(f);
            }
        }
        return file.delete();
    }
}
